home *** CD-ROM | disk | FTP | other *** search
- ;* ENVIRON.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Manipulate Environments (interpreter support) *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL small
- LOCALS @@
-
- INCLUDE "scheme.ash"
- INCLUDE "interprt.ash"
-
- CODESEG
-
- ;************************************************************************
- ;* push environment PUSH-ENV list-of-symbols *
- ;* *
- ;* Purpose: Scheme interpreter support to "push" a new rib onto the *
- ;* current heap allocated environment. *
- ;************************************************************************
- PROC push_env
- get1op
- mov bx, SIZE ENVDEF-OFFSET (TYPE ENVDEF).parent
- mov cx, ENVTYPE
- lea dx, [tmp_reg]
- save <ax, si>
- call alloc_block C, dx, cx, bx
-
- restore <ax> ; fetch pointer to list-of-symbols
- mov bx, ax
- shl ax, 1
- add bx, ax ; bx <- #constants * 3
- add bx, [cb_reg.disp]
- mov ax, [(CODEDEF es:bx).consts.disp]
- mov dl, [(CODEDEF es:bx).consts.page]
-
- mov bx, [tmp_reg.page] ; place previous env pointer in new one,
- mov di, [tmp_reg.disp] ; update stack frame's env pointer
- ldpage es, bx
- mov si, [frameptr]
- xchg bl, [s_stack+si.heap.page]
- mov [(ENVDEF es:di).parent.page], bl
- mov cx, di
- xchg cx, [s_stack+si.heap.disp]
- mov [(ENVDEF es:di).parent.disp], cx
-
- mov [(ENVDEF es:di).names.page], dl ; put list-of-symbols pointer into new environment data object
- mov [(ENVDEF es:di).names.disp], ax
-
- mov [tm2_reg.bpage], NIL_PAGE*2 ; set tm2_reg to initial empty list of values
- mov [tm2_reg.disp], NIL_DISP
-
- cmp dl, 0 ; count number of symbols in the list-of-symbols
- je @@end
- mov [(ENVDEF es:di).values.page], NIL_PAGE*2 ; nil value list to prevent gc problems
- mov [(ENVDEF es:di).values.disp], NIL_DISP
- xor cx, cx
- xor bx, bx
- mov bl, dl ; copy the list-of-symbols pointer
- mov si, ax
- @@next:
- inc cx ; increment list length
- ldpage es, bx ; follow the cdr field of the linked list
- mov bl, [(LISTDEF es:si).cdr.page]
- mov si, [(LISTDEF es:si).cdr.disp]
- cmp bl, 0 ; end of list?
- jne @@next
-
- lea dx, [nil_reg]
- lea ax, [tm2_reg]
- @@cons:
- push cx dx ax
- call cons C, ax, ax, dx ; create value list of nil pointers (linked through car field)
- pop ax dx cx
- loop @@cons
-
- mov bx, [tmp_reg.page] ; reload environment object pointer
- ldpage es, bx ; (may be altered by cons)
- mov di, [tmp_reg.disp]
- @@end:
- mov al, [tm2_reg.bpage] ; store pointer to list-of-values in env object
- mov [(ENVDEF es:di).values.page], al
- mov ax, [tm2_reg.disp]
- mov [(ENVDEF es:di).values.disp], ax
- jmp next_pc
- ENDP push_env
-
- ;************************************************************************
- ;* hash-environment HASH-ENV *
- ;* *
- ;* Purpose: Scheme interpreter support to return a hashed environment *
- ;* *
- ;************************************************************************
- PROC hash_env
- get1op
- save <si>
- mov bx, (HT_SIZE+1) * SIZE POINTER; size of hashed env
- mov cx, ENVTYPE
- lea dx, [tmp_reg]
- push ax
- call alloc_block C, dx, cx, bx
-
- mov bx, [tmp_reg.page]
- corpage bx
- call zero_blk C, bx, [tmp_reg.disp]
- mov bx, [tmp_reg.page]
- mov di, [tmp_reg.disp]
- ldpage es, bx ; es is address of new environment
- mov bx, [frameptr]
- mov al, [s_stack+bx.heap.page] ; point to parent object
- mov bx, [s_stack+bx.heap.disp]
- mov [(ENVDEF es:di).parent.page], al
- mov [(ENVDEF es:di).parent.disp], bx
- pop di ; restore register number
- mov ax, [tmp_reg.page] ; return tmp_reg
- mov bx, [tmp_reg.disp]
- mov [regs+di.bpage], al
- mov [regs+di.disp], bx
- jmp next_pc
- ENDP hash_env
-
- ;************************************************************************
- ;* drop-environment DROP-ENV I(number to drop) *
- ;* *
- ;* Purpose: Scheme interpreter support to drop the most recently *
- ;* allocated rib from the current environment. *
- ;************************************************************************
- PROC drop_env
- get1op
- save <si>
- mov cx, ax ; copy drop count to cx
- mov di, [frameptr]
- xor bx, bx
- mov bl, [s_stack+di.heap.page] ; load environment pointer from
- mov si, [s_stack+di.heap.disp] ; the current stack frame
- @@loop:
- ldpage es, bx
- mov bl, [(ENVDEF es:si).parent.page]
- mov si, [(ENVDEF es:si).parent.disp]
- loop @@loop
- mov [s_stack+di.heap.page], bl ; rib into the stack frame
- mov [s_stack+di.heap.disp], si
- jmp next_pc
- ENDP drop_env
-
- ;************************************************************************
- ;* Macro Support for load/store-environment *
- ;************************************************************************
- MACRO ld_st @@typerror, @@valuerror
- get2op
- save <si>
- xor bh, bh
- mov bl, al
- lea di, [regs+bx]
- save <di>
- mov bl, ah ; copy constant number in di
- mov di, bx
- shl bx, 1
- add di, bx ; di <- constant number * 3
- add di, [cb_reg.disp] ; compute address of code block constant
- xor bh, bh
- mov bl, [(CODEDEF es:di).consts.page]
- cmp [ptype+bx], SYMBTYPE ; it is a symbol, isn't it?
- jne @@typerror
- mov cx, bx ; copy symbol pointer into cx:dx
- mov dx, [(CODEDEF es:di).consts.disp]
- mov si, [frameptr]
- mov bl, [s_stack+si.heap.page] ; load current env pointer in bx:si
- mov si, [s_stack+si.heap.disp]
- call srch_all ; search environment for symbol
- restore <di>
- cmp bx, 0 ; was symbol found in environment?
- je @@valuerror
- ldpage es, bx
- ENDM
-
- ;************************************************************************
- ;* Load From Environment LD-ENV R(dest),C(symbol) *
- ;* *
- ;* Purpose: Scheme interpreter support to load from the current *
- ;* environment. *
- ;************************************************************************
- PROC ld_env
- ld_st @@notsym, @@notfound
- mov al, [(LISTDEF es:si).cdr.page]
- mov bx, [(LISTDEF es:si).cdr.disp]
- mov [(REG di).bpage], al ; store value in destination register
- mov [(REG di).disp], bx
- jmp next_pc
-
- @@notsym:
- lea bx, [@@msg]
- jmp src_err
- DATASEG
- @@msg DB "ld-env", 0
- CODESEG
-
- @@notfound:
- corpage cx
- push es ; saves es over C call
- xor ax, ax ; signal current environment being used
- call sym_undefined C, cx, dx, ax, di
- pop es
- restore <si>
- sub si, 3 ; back up to retry the ld/st
- jmp sch_err
- ENDP ld_env
-
- ;************************************************************************
- ;* Store Into Environment ST-ENV R(value),C(symbol) *
- ;* *
- ;* Purpose: Scheme interpreter support to store into the current *
- ;* environment. *
- ;************************************************************************
- PROC st_env
- ld_st @@notsym, @@notfound
- mov al, [(REG di).bpage] ; store value into cdr field of cell
- mov bx, [(REG di).disp]
- mov [(LISTDEF es:si).cdr.page], al
- mov [(LISTDEF es:si).cdr.disp], bx
- jmp next_pc
-
- @@notsym:
- lea bx, [@@msg]
- jmp src_err
- DATASEG
- @@msg DB "st-env", 0
- CODESEG
- @@notfound:
- corpage cx
- push es ; saves es over C call
- call not_lexically_bound C, cx, dx
- pop es
- restore <si>
- sub si, 3 ; back up to retry the ld/st
- jmp sch_err
- ENDP st_env
-
- ;************************************************************************
- ;* al al ah *
- ;* Define in Environment DEFINE R(d=s1),R(s2),R(s3) *
- ;* s1=sym,s2=val,s3=env/nil *
- ;* *
- ;* Purpose: Scheme interpreter support to define a symbol in a given *
- ;* environment. This routine supports the MIT Scheme construct *
- ;* (set! (access sym env) value). In essence, the current env *
- ;* is searched for sym. If found, then its binding is modified *
- ;* to value. Otherwise, a new binding is added to the current *
- ;* environment. *
- ;************************************************************************
- PROC def_env
- get1op
- mov di, ax ; get symbol register number in di
- add di, OFFSET regs
- get2op
- save <si, di, ax> ; save loc ptr, dest reg addr, val/env opnds
- mov bx, [(REG di).page]
- cmp [ptype+bx], SYMBTYPE ; is first operand a symbol?
- je @@typeok
- @@error:
- lea bx, [@@msg]
- jmp src_err
- DATASEG
- @@msg DB "define-env", 0
- CODESEG
- @@typeok:
- mov cx, bx ; place symbol pointer into cx:dx
- mov dx, [(REG di).disp]
- mov bl, ah ; validate env operand
- mov si, [regs+bx.disp] ; load environment pointer into bx:si
- mov bl, [regs+bx.bpage]
- cmp [ptype+bx], ENVTYPE ; is it an environment object?
- je @@ok
- cmp bl, 0 ; is it a nil pointer?
- jne @@error
- mov si, [frameptr]
- mov bl, [s_stack+si.heap.page] ; default env to current env
- mov si, [s_stack+si.heap.disp]
- @@ok:
- push bx si ; save environment pointer on stack
- call srch_all
- restore <ax> ; 2nd and 3rd operands
- cmp bl, 0 ; was symbol found?
- je @@bind
- add sp, 4 ; clean stack
- ldpage es, bx
- mov bl, al
- mov al, [regs+bx.bpage] ; set cdr of value cell to the
- mov bx, [regs+bx.disp] ; contents of the value register
- mov [(LISTDEF es:si).cdr.page], al
- mov [(LISTDEF es:si).cdr.disp], bx
- jmp next_pc
-
- @@bind:
- restore <di> ; restore symbol register address
- pop [tm2_reg.disp] ; restore env pointer in local tmp_reg
- pop [tm2_reg.page]
- mov bl, al ; compute value register address
- add bx, OFFSET regs
- lea si, [tm2_reg]
- call bind_it C, di, bx, si
- jmp next_pc
- ENDP def_env
-
- ;************************************************************************
- ;* Set Global Environment SET-GLOB-ENV! R(value) *
- ;* *
- ;* Purpose: Scheme interpreter support to initialize the Global *
- ;* Environment Register (GNV_reg). *
- ;************************************************************************
- PROC set_gnv
- get1op
- mov di, ax
- add di, OFFSET regs ; compute reg address in di
- mov ax, [(REG di).disp]; load pointer to new global environment
- mov bx, [(REG di).page]
- cmp [ptype+bx], ENVTYPE ; it's an environment, isn't it?
- jne @@error
- xchg [gnv_reg.bpage], bl ; copy env pointer to GNV_reg
- xchg [gnv_reg.disp], ax
- mov [(REG di).bpage], bl ; store previous value of GNV_reg
- mov [(REG di).disp], ax
- jmp next
-
- @@error:
- save <si> ; save the location pointer
- lea bx, [@@msg]
- jmp src_err
- @@msg DB "set-global-env!", 0
- ENDP set_gnv
-
- ;************************************************************************
- ;* al ah *
- ;* Load from Global Environment LD-GLOBAL R(d),C(s1) *
- ;* s1=symbol *
- ;* *
- ;* Purpose: Scheme interpreter support to retrieve values for symbols *
- ;* defined in the current global environment. *
- ;* *
- ;* Note: This instruction is an optimization of the LD-ENV operation. *
- ;* Here, the environment operand defaults to the current *
- ;* global environment, which is pointer to by GNV_reg. *
- ;************************************************************************
- PROC ld_globl
- get2op
- mov bl, al
- lea di, [regs+bx] ; compute the destination register's address
- save <si, di>
- mov bl, ah ; copy the constant number
- mov si, bx ; si <- constant number * 3
- shl si, 1
- add si, bx
- add si, [cb_reg.disp] ; add in displacement of current code block
- mov bl, [(CODEDEF es:si).consts.page]
- mov dx, [(CODEDEF es:si).consts.disp]
- in_ld_globl:
- cmp [ptype+bx], SYMBTYPE ; it is a symbol, isn't it?
- jne @@error
- mov cx, bx
- mov bl, [gnv_reg.bpage] ; load pointer to the global environment
- mov si, [gnv_reg.disp]
- push cx dx ; search the global environment for the symbol-- test to see if found
- call srch_all
- restore <di>
- cmp bl, 0 ; was symbol found?
- je @@notfound
- add sp, 4 ; clean stack
- ldpage es, bx
- mov al, [(LISTDEF es:si).cdr.page]
- mov bx, [(LISTDEF es:si).cdr.disp]
- mov [(REG di).bpage], al ; copy cdr field of value cell
- mov [(REG di).disp], bx ; into destination register
- jmp next_pc
- @@error:
- lea bx, [@@msg]
- jmp src_err
- DATASEG
- @@msg DB "ld-global", 0
- CODESEG
- @@notfound:
- pop dx cx ; restore symbol pointer
- corpage cx
- lea ax, [gnv_reg]
- push es ; saves es over C call
- call sym_undefined C, cx, dx, ax, di
- pop es
- restore <si>
- sub si, 3 ; back up location pointer to retry load
- jmp sch_err
- ENDP ld_globl
-
- ;************************************************************************
- ;* al ah *
- ;* Load from Global Environment (reg operand) LD-GLOBAL-R R(d),R(s1) *
- ;* s1=symbol *
- ;* *
- ;* Purpose: Scheme interpreter support to retrieve values for symbols *
- ;* defined in the current global environment. *
- ;* *
- ;* Note: This instruction is an optimization of the LD-ENV operation. *
- ;* Here, the environment operand defaults to the current *
- ;* global environment, which is pointer to by GNV_reg. *
- ;************************************************************************
- PROC ld_globr
- get2op
- mov bl, al
- lea di, [regs+bx]
- save <si, di>
- mov bl, ah
- mov dx, [regs+bx.disp] ; load symbol's displacement & page
- mov bl, [regs+bx.bpage]
- jmp in_ld_globl ; continue process as ld-global
- ENDP ld_globr
-
- ;************************************************************************
- ;* al ah *
- ;* Define in Global Environment DEFINE! R(d=s1),C(s2) *
- ;* s1=value,s2=symbol *
- ;* *
- ;* Purpose: Scheme interpreter support to assign a variable in the *
- ;* current "global" environment. *
- ;* *
- ;* Note: This instruction is an optimization of the DEFINE-ENV *
- ;* operation. Here, the environment operand defaults to *
- ;* the current global environment, which is pointed to by *
- ;* GNV_reg. *
- ;************************************************************************
- PROC define
- get2op
- mov bl, ah ; copy constant number to bx
- xor ah, ah
- mov di, ax
- add di, OFFSET regs ; and register to di
- save <si, di>
- mov si, bx
- shl si, 1
- add si, bx ; si <- constant number * 3
- add si, [cb_reg.disp] ; add starting offset of current code block
- mov bl, [(CODEDEF es:si).consts.page]
- mov dx, [(CODEDEF es:si).consts.disp]
- cmp [ptype+bx], SYMBTYPE ; it is a symbol, isn't it?
- jne @@error
- mov cx, bx ; put symbol pointer into cx:dx
- push cx dx
- mov bl, [gnv_reg.bpage] ; load global environment pointer into bx:si
- mov si, [gnv_reg.disp]
- call srch_env
- cmp bl, 0
- je @@new
- add sp, 4 ; correct stack
- restore <di>
- ldpage es, bx
- mov al, [(REG di).bpage]
- mov bx, [(REG di).disp]
- mov [(LISTDEF es:si).cdr.page], al
- mov [(LISTDEF es:si).cdr.disp], bx
- jmp next_pc
-
- @@new: ; symbol wasn't found. create new binding in current global environment
- mov ax, sp ; get address of symbol
-
- ; In case you're wondering what just went on with the above instruction,
- ; the page and displacement of the symbol to be bound are residing in the
- ; correct order on the top of the stack. The "mov ax,sp" captures the
- ; address of said pointer so that it may be used as an argument to
- ; sym_bind, below.
-
- lea bx, [gnv_reg]
- call bind_it C, ax, [(SINT_ARG bp-SIZE SINT_ARG).sv_di], bx
- ; call bind_it C, ax, [save_di], bx
- add sp, 4 ; restore stack
- jmp next_pc
-
- @@error:
- lea bx, [@@msg]
- jmp src_err
- DATASEG
- @@msg DB "define!", 0
- CODESEG
- ENDP define
-
- ;************************************************************************
- ;* al ah *
- ;* Define in Global Environment ST-GLOBAL R(d=s1),C(s2) *
- ;* s1=value,s2=symbol *
- ;* *
- ;* Purpose: Scheme interpreter support to assign a variable in the *
- ;* current "global" environment. *
- ;* *
- ;* Note: This instruction is an optimization of the ST-ENV *
- ;* operation. Here, the environment operand defaults to *
- ;* the current global environment, which is pointed to by *
- ;* GNV_reg. *
- ;************************************************************************
- PROC st_globl
- get2op
- mov bl, ah ; copy constant number to bx
- xor ah, ah
- mov di, ax
- add di, OFFSET regs ; and register to di
- save <si, di>
- mov si, bx
- shl si, 1
- add si, bx ; si <- constant number * 3
- add si, [cb_reg.disp] ; add starting offset of current code block
- mov bl, [(CODEDEF es:si).consts.page]
- mov dx, [(CODEDEF es:si).consts.disp]
- cmp [ptype+bx], SYMBTYPE ; it is a symbol, isn't it?
- jne @@error
- mov cx, bx ; put symbol pointer into cx:dx
- push cx dx
- mov bl, [gnv_reg.bpage]
- mov si, [gnv_reg.disp]
- call srch_all
- restore <di>
- cmp bl, 0
- je @@notfound
- add sp, 4 ; clean stack
- ldpage es, bx
- mov al, [(REG di).bpage]
- mov bx, [(REG di).disp]
- mov [(LISTDEF es:si).cdr.page], al
- mov [(LISTDEF es:si).cdr.disp], bx
- jmp next_pc
- @@notfound:
- pop dx cx
- corpage cx
- push es ; saves es over C call
- call not_globally_bound C, cx, dx, di
- pop es
- restore <si>
- sub si, 3 ; back up pointer up to retry the store
- jmp sch_err
- @@error:
- lea bx, [@@msg]
- jmp src_err
- DATASEG
- @@msg DB "st-global", 0
- CODESEG
- ENDP st_globl
-
- ;************************************************************************
- ;* Environment Predicate ENV? object *
- ;* *
- ;* Purpose: Scheme interpreter support to test for an environment *
- ;* data object. *
- ;************************************************************************
- PROC env_p
- get1op
- mov di, ax
- add di, OFFSET regs
- mov bx, [(REG di).page]
- cmp [ptype+bx], ENVTYPE ; is operand an environment?
- je @@itis
- mov [(REG di).bpage], NIL_PAGE*2
- mov [(REG di).disp], NIL_DISP
- jmp next
- @@itis:
- mov [(REG di).bpage], T_PAGE*2
- mov [(REG di).disp], T_DISP
- jmp next ; return to interpreter
- ENDP env_p
-
- ;************************************************************************
- ;* Make Environment MK-ENV dest *
- ;* *
- ;* Purpose: Scheme interpreter support to return a pointer to the *
- ;* current environment. *
- ;************************************************************************
- PROC mk_env
- get1op
- mov di, ax
- mov bx, [frameptr]
- mov al, [s_stack+bx.heap.page] ; load current env pointer from stack
- mov bx, [s_stack+bx.heap.disp]
- mov [regs+di.bpage], al ; and put in destination register
- mov [regs+di.disp], bx
- jmp next
- ENDP mk_env
-
- ;************************************************************************
- ;* Environment Parent ENV-PARENT env *
- ;* *
- ;* Purpose: Scheme interpreter return the "parent" of a given *
- ;* environment. *
- ;************************************************************************
- PROC env_par
- get1op
- save <si>
- mov di, ax
- add di, OFFSET regs
- mov bx, [(REG di).page]
- cmp [ptype+bx], ENVTYPE
- jne @@error
- mov si, [(REG di).disp] ; load pointer to environment object
- ldpage es, bx
- mov al, [(ENVDEF es:si).parent.page] ; load parent pointer from env object
- mov bx, [(ENVDEF es:si).parent.disp]
- mov [(REG di).bpage], al ; and put in destination register
- mov [(REG di).disp], bx
- jmp next_pc
- @@error:
- lea bx, [@@msg]
- jmp src_err
- DATASEG
- @@msg DB "environment-parent", 0
- CODESEG
- ENDP env_par
-
- ;************************************************************************
- ;* Lookup In Environment ENV-LU R(d=s1),R(s2) *
- ;* s1=symbol,s2=env *
- ;************************************************************************
- PROC env_lu
- get2op
- xor bh, bh ; fetch and validate symbol pointer
- mov bl, al
- lea di, [regs+bx]
- save <si, di>
- mov cx, [(REG di).page]; copy symbol pointer into cx:dx
- mov dx, [(REG di).disp]
- mov bx, cx ; test to make sure that first operand
- cmp [ptype+bx], SYMBTYPE ; is a symbol
- jne @@error
- mov bl, ah ; fetch and validate environment pointer
- mov si, [regs+bx.disp] ; copy environment pointer into bx:si
- mov bl, [regs+bx.bpage]
- cmp [ptype+bx], ENVTYPE ; it is an env, isn't it?
- jne @@error
- call srch_all
- restore <di>
- mov [(REG di).bpage], bl
- mov [(REG di).disp], si
- jmp next_pc
- @@error:
- lea bx, [@@msg]
- jmp src_err
- DATASEG
- @@msg DB "env-lu", 0
- CODESEG
- ENDP env_lu
-
- ;************************************************************************
- ;* Local Support - Search Environment (all of it) *
- ;* *
- ;* Input Parameters: cx:dx - search symbol *
- ;* bx:si - environment chain pointer *
- ;* *
- ;* Output Parameters: bx:si - value cell for symbol *
- ;* trashes: cx, dx *
- ;************************************************************************
- PROC srch_all near
- @@loop:
- push bx si cx dx ; save pointer to current rib
- call srch_env ; search rib for desired symbol
- cmp bx, 0 ; was symbol found?
- jne @@done
- pop dx cx si bx ; restore pointer to current rib
- ldpage es, bx
- mov bl, [(ENVDEF es:si).parent.page]
- mov si, [(ENVDEF es:si).parent.disp]
- cmp bx, 0 ; does parent rib exist?
- jne @@loop
- jmp @@fail
- @@done:
- add sp, 8 ; dump env pointer off stack
- @@fail:
- ret
- ENDP srch_all
-
- ;************************************************************************
- ;* Local Support - Search Environment (one rib) *
- ;* *
- ;* Input Parameters: cx:dx - search symbol *
- ;* bx:si - environment chain pointer *
- ;* *
- ;* Output Parameters: bx:si - value cell for symbol *
- ;************************************************************************
- PROC srch_env near
- ldpage es, bx
- cmp [(ENVDEF es:si).len], SIZE ENVDEF ; hash table or "rib"?
- je @@rib
- jmp @@hashtable
- @@rib:
- push bx si ; save pointer to environment
- mov ax, 1 ; initialize counter
- xor bx, bx
- mov bl, [(ENVDEF es:si).names.page] ; load pointer to list of symbols
- mov si, [(ENVDEF es:si).names.disp]
- @@ribmore:
- cmp bl, 0 ; more symbols in this rib?
- je @@ribnotfound
- ldpage es, bx
- cmp dx, [(LISTDEF es:si).car.disp]
- jne @@ribnext
- cmp cl, [(LISTDEF es:si).car.page]
- je @@ribfound
- @@ribnext:
- inc ax ; increment symbol count
- mov bl, [(LISTDEF es:si).cdr.page]
- mov si, [(LISTDEF es:si).cdr.disp]
- jmp @@ribmore
- @@ribfound:
- mov cx, ax ; move counter symbol counter to cx
- pop si bx ; recover pointer to environment chain
- ldpage es, bx
- mov bl, [(ENVDEF es:si).values.page]
- mov si, [(ENVDEF es:si).values.disp]
- jmp @@ribskip
- @@ribloop:
- ldpage es, bx ; follow chain through car field of linked list
- mov bl, [(LISTDEF es:si).car.page]
- mov si, [(LISTDEF es:si).car.disp]
- @@ribskip:
- loop @@ribloop
- ret
-
- @@ribnotfound:
- add sp, 4 ; drop env pointer off stack
- ret
-
- ;************************************************************************
- ;* Hash Table Environment Format *
- ;************************************************************************
- @@hashtable:
- DATASEG
- @@temp REG <>
- CODESEG
- push bx
- mov [@@temp.page], cx ; store symbol pointer in tmp_reg
- mov [@@temp.disp], dx
- lea ax, [@@temp]
- call sym_hash C, ax
- cmp ax, HT_SIZE ; valid hash value returned?
- jae @@hasherror
- pop bx ; restore pointer to environment object
- add si, ax ; env-ptr += hash-value * 3
- shl ax, 1 ; fetch symbol chain from indicated hash table bucket
- add si, ax
- ldpage es, bx ; load environment page's paragraph address
- mov bl, [(ENVDEF es:si).names.page]
- cmp bl, 0 ; is hash chain empty?
- je @@hashnotfound
- mov si, [(ENVDEF es:si).names.disp]
- ldpage es, bx
- mov dx, [@@temp.page] ; restore symbol pointer into dx:ax
- mov ax, [@@temp.disp]
- call lookup
- mov si, di ; put pointer returned in bx:si
- ret
-
- @@hasherror:
- add sp, 4 ; drop saved arguments off stack
- xor bx, bx ; return a nil pointer
- @@hashnotfound:
- xor si, si
- ret
- ENDP srch_env
-
- ;************************************************************************
- ;* Symbol Binding Routine *
- ;* *
- ;* Purpose: Borland C callable routine to return the bind a value to *
- ;* a symbol in a given environment. *
- ;* *
- ;* Calling Sequence: sym_bind(symbol, value, environment) *
- ;* where symbol - register containing the symbol *
- ;* pointer *
- ;* value - register containing the value to *
- ;* be assigned *
- ;* environment - register containing a pointer to *
- ;* the environment in which the *
- ;* binding is to take place *
- ;************************************************************************
- PROC C sym_bind far USES si di, @@symbol, @@value, @@env
- mov bx, [@@symbol]
- mov cx, [(REG bx).page]
- mov dx, [(REG bx).disp]
- mov bx, [@@env]
- mov si, [(REG bx).disp]
- mov bx, [(REG bx).page]
- call srch_all
- cmp bl, 0 ; symbol found in environment?
- je @@new
- ldpage es, bx
- mov bx, [@@value]
- mov al, [(REG bx).bpage] ; copy value from value register
- mov bx, [(REG bx).disp]
- mov [(LISTDEF es:si).cdr.page], al ; into the cdr field of the value cell
- mov [(LISTDEF es:si).cdr.disp], bx
- jmp @@ret
-
- in_sym_bind:
- @@new:
- mov si, [@@env]
- mov bx, [(REG si).page]
- mov si, [(REG si).disp]
- ldpage es, bx
- cmp [(ENVDEF es:si).len], SIZE ENVDEF
- je @@rib
- jmp @@hashtable
- @@rib:
- ;************************************************************************
- ;* bind symbol to "rib" format environment *
- ;************************************************************************
- mov al, [(ENVDEF es:si).names.page]
- mov bx, [(ENVDEF es:si).names.disp]
- mov [tmp_reg.bpage], al
- mov [tmp_reg.disp], bx
- lea ax, [tmp_reg]
- call cons C, ax, [@@symbol], ax ; cons symbol to front of name list
- mov bx, [@@env]
- mov si, [(REG bx).disp] ; it may have been relocated during the the cons
- mov bx, [(REG bx).page]
- ldpage es, bx
- mov al, [tmp_reg.bpage] ; update name list pointer
- mov bx, [tmp_reg.disp]
- mov [(ENVDEF es:si).names.page], al
- mov [(ENVDEF es:si).names.disp], bx
-
- mov al, [(ENVDEF es:si).values.page]
- mov bx, [(ENVDEF es:si).values.disp]
- mov [tmp_reg.bpage], al
- mov [tmp_reg.disp], bx
- lea ax, [tmp_reg]
- call cons C, ax, ax, [@@value] ; cons value to front of value list
- mov bx, [@@env]
- mov si, [(REG bx).disp]
- mov bx, [(REG bx).page]
- ldpage es, bx
- mov al, [tmp_reg.bpage]
- mov bx, [tmp_reg.disp]
- mov [(ENVDEF es:si).values.page], al
- mov [(ENVDEF es:si).values.disp], bx
- jmp @@ret
- ;************************************************************************
- ;* bind symbol to "hash table" format environment *
- ;************************************************************************
- @@hashtable:
- lea ax, [tmp_reg]
- call cons C, ax, [@@symbol], [@@value]
- lea ax, [tmp_reg]
- lea bx, [nil_reg]
- call cons C, ax, ax, bx
- call sym_hash C, [@@symbol]
- mov bx, ax ; multiply hash value by 3
- shl ax, 1
- add bx, ax
- mov si, [@@env]
- add bx, [(REG si).disp]
- mov si, [(REG si).page]
- ldpage es, si
- mov ax, [tmp_reg.page] ; load pointer to second list cell
- mov dx, [tmp_reg.disp]
- mov si, ax
- mov di, dx
- xchg al, [(ENVDEF es:bx).names.page] ; swap list header in environment hash
- xchg dx, [(ENVDEF es:bx).names.disp]
- ldpage es, si
- mov [(LISTDEF es:di).cdr.page], al ; update entry in env hash table
- mov [(LISTDEF es:di).cdr.disp], dx
- @@ret:
- ret
- ENDP sym_bind
-
- ;************************************************************************
- ;* Symbol Forced Binding Routine *
- ;* (a shortcut in sym_bind) *
- ;* *
- ;* !!! This procedure HAS to have the same parameters as the previous *
- ;************************************************************************
- PROC C bind_it far USES si di, @@symbol, @@value, @@env
- jmp in_sym_bind
- ENDP bind_it
-
- ;************************************************************************
- ;* eq_lookup Routine *
- ;* *
- ;* Borland C callable routine to simulate a lookup for a pointer in a *
- ;* list of pairs (ASSQ) *
- ;* *
- ;* Calling Sequence: eq_lookup(item, list) *
- ;* where item - register containing the object *
- ;* to seek, *
- ;* list - register containing a pointer to *
- ;* the list of pairs to be searched*
- ;* *
- ;* It points item to the pair (item . value) and return true if found, *
- ;* or leave item unchanged and return false. *
- ;************************************************************************
- PROC C eq_lookup far USES si di, @@item, @@list
- mov si, [@@item]
- mov di, [@@list]
- mov ax, [(REG si).disp]
- mov dx, [(REG si).page]
- mov bx, [(REG di).page]
- mov si, [(REG di).disp]
- call lookup ; search
- xor ax, ax ; assume not found
- or bl, bl ; bl = 0 if not found
- jz @@return
- inc ax ; return true
- mov si, [@@item]
- mov [(REG si).disp], di
- mov [(REG si).bpage], bl
- @@return:
- ret
- ENDP eq_lookup
-
- ;************************************************************************
- ;* Symbol Lookup Routine *
- ;* *
- ;* Purpose: Borland C callable routine to return the value bound to *
- ;* a symbol in a given environment. *
- ;* *
- ;* Calling Sequence: sym_lookup(symbol, environment) *
- ;* where symbol - register containing the symbol *
- ;* pointer *
- ;* environment - register containing a pointer to *
- ;* the environment to be searched *
- ;************************************************************************
- PROC C sym_lookup far USES si di, @@symbol, @@env
- mov bx, [@@symbol]
- mov cx, [(REG bx).page]
- mov dx, [(REG bx).disp]
- mov bx, [@@env]
- mov si, [(REG bx).disp]
- mov bx, [(REG bx).page]
- call srch_all
- xor ax, ax ; assume search failed
- or bl, bl ; symbol found in environment?
- jz @@ret
- ldpage es, bx
- mov bx, [@@symbol]
- mov al, [(LISTDEF es:si).cdr.page] ; copy current binding into the
- mov cx, [(LISTDEF es:si).cdr.disp]
- mov [(REG bx).bpage], al ; argument register
- mov [(REG bx).disp], cx
- mov ax, 1 ; return true
- @@ret:
- ret
- ENDP sym_lookup
-
- ;************************************************************************
- ;* Symbol Hashing Routine *
- ;* *
- ;* Purpose: Borland C callable routine to return the hash value for *
- ;* a given symbol. *
- ;* *
- ;* Calling Sequence: hash = sym_hash(reg) *
- ;* reg - register containing symbol pointer *
- ;* hash - the hash value (if page/disp don't point *
- ;* to a symbol, -1 is returned) *
- ;* *
- ;* Methods Used: The hash value is computed by summing the characters *
- ;* of the symbol and returning the remainder on division *
- ;* by the length of the hash table (HT_SIZE). *
- ;* *
- ;* Note: This routine must return the same hash value as the routine *
- ;* "hash" in SUPPORT.C. If the hashing algorithm is *
- ;* changed, it must be changed in both routines. *
- ;************************************************************************
- PROC C sym_hash far USES di si, @@reg
- mov di, [@@reg]
- mov bx, [(REG di).page]
- cmp [ptype+bx], SYMBTYPE ; is object a symbol?
- jne @@error
- ldpage es, bx
- mov si, [(REG di).disp]
- xor ah, ah ; fetch the symbol's hash key
- mov al, [(SYMDEF es:si).hashkey]
- @@ret:
- ret
- @@error:
- mov ax, -1 ; return a hash value of -1 (invalid)
- jmp @@ret
- ENDP sym_hash
-
- END